package com.swipemaster.common;

import java.text.DecimalFormat;

import android.content.Context;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.util.DisplayMetrics;
import android.view.WindowManager;

import com.swipemaster.R;

/** Class storing all constant values. Constants IN CAPITAL LETTERS are in universal units, if they describe length,
 * position or speed. They have their equivalents in camelCaseLetters, but in screen physical units, px or px/ms.
 * Usually, we will call functions with universal units as arguments, for convenience. They will get recalculated in
 * constructors to screen units for use in the nearest future. */
public class Const
{
	/** Total number of levels. */
	public static final int LEVELS = 48;
	/** Initial number of free levels. */
	public static final int FREE_LEVELS = 48;
	/** Maximum number of enemies per level. */
	public static final int MAX_ENEMIES = 42;

	/** Application's public key. The key itself is not secret information, but we don't want to make it easy for an
	 * attacker to replace the public key with one of their own and then fake messages from the server. ProGuard makes
	 * only a little bit harder to find this key. */
	public static final char[] BASE64_ENCODED_PUBLIC_KEY =
	{ 'M', 'I', 'I', 'B', 'I', 'j', 'A', 'N', 'B', 'g', 'k', 'q', 'h', 'k', 'i', 'G', '9', 'w', '0', 'B', 'A', 'Q',
			'E', 'F', 'A', 'A', 'O', 'C', 'A', 'Q', '8', 'A', 'M', 'I', 'I', 'B', 'C', 'g', 'K', 'C', 'A', 'Q', 'E',
			'A', 'q', 'B', 'Z', 'A', 'G', '2', 'U', '7', 'h', 'o', '5', 'D', 'O', 'o', 'K', 'b', 'S', 'y', 'N', 'K',
			'F', 'L', '3', 'N', '9', '7', 'R', '/', 'm', 'n', '9', '0', 'S', 'h', 'J', 'f', '1', '1', 'm', 'G', '4',
			'Y', 'U', 'u', 'd', 'x', '0', 'c', 'T', 'y', '6', '5', 'Z', 'b', 'F', 'b', 'q', 'T', 'K', 'R', 'Q', 'G',
			'z', 'o', 'y', 'o', '1', 'C', 'o', 'i', 'x', 't', 'O', '+', 'U', 'X', 'p', 's', 'd', 'Z', '/', '5', 'j',
			'R', 'H', '6', 'r', 'w', 't', '7', 'h', '+', 'j', 'j', '6', 'o', '8', 'q', 'H', 'j', 'o', 'c', 'R', 'W',
			'd', 'O', 'b', 'x', 'e', 'g', 'R', 'x', 'J', 'k', 'g', 'I', 'n', '1', 'A', 'x', 'f', 'c', '7', 'x', 'a',
			'T', 'e', 'p', 'm', '5', 'z', 't', 'I', 'c', 'j', '9', '3', 'E', 'y', 'o', 'E', '+', 'P', '2', 'p', 'p',
			'w', 'c', 'c', 'g', '/', 'P', 'p', 'p', 'e', 'h', 'O', '1', 'W', 'c', 'L', 'c', '+', 'f', '+', '4', '7',
			'Y', 'V', 'H', 'a', 'f', 'O', '8', 'D', '0', 'p', 'q', 'c', 'X', '0', 'S', '8', 'z', '5', 'd', 'y', '0',
			'7', 'A', 'u', 'W', 'v', 'D', 'U', 'N', '5', 'C', '/', 'l', 'J', 'M', 'A', 'E', 'W', 'b', 'o', 'F', 'o',
			'd', 't', 'O', 'q', 'm', 'p', '7', 'x', 'm', '4', '1', '6', 'U', 'S', 's', 'v', 'o', 'H', 'D', 'm', 'B',
			'P', 'e', 'y', 'M', 'b', '/', '+', 'w', 'p', 'J', 'B', '5', 'f', 'A', 'A', '7', 'L', 'U', 'G', 'f', 'e',
			'o', 'l', '0', '5', 'P', '+', '1', 'k', 'u', 'c', 'd', 'i', 'E', 'A', 'U', 'N', 'v', '6', 'd', 'Z', 'g',
			'3', 'z', 'W', 'Z', 'V', 'l', '1', 'z', 'Z', 'm', 'M', 'K', 'n', 'a', '9', 's', '9', 'Y', 'P', 'f', '/',
			'X', '+', 'B', 'g', 'A', 'J', 'K', 'b', 'P', 'R', 'Q', '6', 'I', '9', 'R', '2', '8', 'v', 'R', 'x', '4',
			'e', 'v', 'H', 'p', 'r', 'z', 'G', 'S', 'U', 'O', 'w', '/', 't', 'v', 'U', 'F', 'O', 'x', 'h', 'T', 'a',
			'p', 'T', '4', '+', 'Z', 'T', 'w', 'I', 'D', 'A', 'Q', 'A', 'B', };

	/** Speed of enemies. Universal units. */
	public static final double MAX_SPEED = 0.0005;
	public static final double MIN_SPEED = 0.0002;

	/** Universal speed up scale. */
	public static final double UNIVERSAL_SPEED_UP = 1.2;

	/** Standard radius for circles. Universal units. */
	public static final double RADIUS = 0.04;

	/** Codes for directions instead of enums, for performance reasons. */
	public static final int UP = 10;
	public static final int RIGHT = 11;
	public static final int DOWN = 12;
	public static final int LEFT = 13;
	public static final int CENTRAL = 14;

	/** Circle with center in current player position. Player moves only if user touch this circle. Radius is given in
	 * universal units, as part of the diagonal. */
	public static final double UNIVERSAL_TOUCH_RADIUS = 0.25;
	/** Radius of touch circle in screen units, pixels. */
	public int touchRadius;

	/** How many ms we are waiting between repaints. The higher, the events are handled faster. */
	public static final int MS_BETWEEN_PAINT = 10;

	/** duration of animation after clicking on button in UI */
	public static final int BUTTON_CLICK_ANIM_DURATION = 200;

	/** Screen width in px. */
	public int width;
	/** Screen height in px. */
	public int height;
	/** Length of diagonal in px. */
	public int diagonal;
	/** Height to diagonal ratio. */
	public double htd;
	/** Diagonal to height ratio. */
	public double dth;
	/** Width to diagonal ratio. */
	public double wtd;

	/** Maximum number of characters in user name. */
	public static final int MAX_NAME_LENGTH = 15;

	/** In order to format doubles. */
	public static final DecimalFormat decimalFormat = new DecimalFormat("#.##");

	/** Fancy font. */
	public Typeface font;
	public static String FONT_FILENAME = "CoolDots.ttf";

	/** Used to draw time counter on the game surface. */
	public Paint timeCounterRedPaint;
	public Paint timeCounterGreenPaint;
	public int timeCounterTextSize;

	/** Texts shadows constants */
	public static final int titleShadowRadiousDp = 3;
	public static final int titleShadowDxDp = 2;
	public static final String titleTextShadowColorString = "#cf0d0d";
	public static final int scoreShadowRadiousDp = 2;
	public static final int scoreShadowDxDp = 2;
	public static final String scoreShadowColorString = "#cf0d0d";

	private final DisplayMetrics metrics = new DisplayMetrics();

	static
	{
		decimalFormat.setMinimumFractionDigits(2);
		decimalFormat.setMaximumFractionDigits(2);
	}

	public int dpToPx(int dp)
	{
		return Math.round(dp * Global.app.getResources().getDisplayMetrics().density);
	}

	public String getLevelTypeName(boolean isPuzzle)
	{
		if (isPuzzle)
		{
			return Global.app.getString(R.string.puzzle);
		}
		else
		{
			return Global.app.getString(R.string.survival);
		}
	}

	public static int getRand(int min, int max)
	{
		return (int) (min + (Math.random() * (max - min)));
	}

	/** Return resource id of image representing given number of stars. If number of stars is not 0, 1, 2 or 3, it
	 * returns resource id = 0. It points to no image at all.
	 * @param stars Number of stars. 0, 1, 2 or 3.
	 * @return Resource id to image of 0, 1, 2 or 3 stars or 0 - no image. */
	public static int getStarsResource(int stars)
	{
		switch (stars)
		{
		case 0:
			return R.drawable.zero_stars_gray;
		case 1:
			return R.drawable.one_stars_gray;
		case 2:
			return R.drawable.two_stars_gray;
		case 3:
			return R.drawable.three_stars;
		}
		return 0;
	}

	public Const()
	{
		setGlobalScreenDimensions();

		font = Typeface.createFromAsset(Global.app.getAssets(), Const.FONT_FILENAME);

		timeCounterTextSize = diagonal / 25;

		timeCounterRedPaint = new Paint();
		timeCounterRedPaint.setARGB(150, 200, 50, 50);
		timeCounterRedPaint.setTypeface(font);
		timeCounterRedPaint.setTextSize(timeCounterTextSize);

		timeCounterGreenPaint = new Paint(timeCounterRedPaint);
		timeCounterGreenPaint.setARGB(150, 50, 200, 50);

		Bitmaps.load();
	}

	private void setGlobalScreenDimensions()
	{
		WindowManager manager = (WindowManager) Global.app.getSystemService(Context.WINDOW_SERVICE);
		manager.getDefaultDisplay().getMetrics(metrics);
		setScreen(metrics.widthPixels, metrics.heightPixels, metrics.scaledDensity);
	}

	/** Set screen constants.
	 * @param width Width of screen in px.
	 * @param height Height of screen in px.
	 * @param density Density of screen px/dp */
	public void setScreen(int width, int height, double density)
	{
		this.width = width;
		this.height = height;
		this.diagonal = Coords.pythagoras(width, height);
		this.htd = (double) height / diagonal;
		this.dth = (double) diagonal / height;
		this.wtd = (double) width / diagonal;
		this.touchRadius = (int) (UNIVERSAL_TOUCH_RADIUS * diagonal);
	}
}